// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RoleEnvironmentExtensions.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Exception for errors when handling Windows Azure Cloud Drives.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

using AzureContrib.WindowsAzure.Diagnostics;
using AzureContrib.WindowsAzure.ServiceRuntime.Properties;

namespace AzureContrib.WindowsAzure.ServiceRuntime
{
	/// <summary>
	/// Access to configuration settings
	/// </summary>
	public static class RoleEnvironmentExtensions
	{
		/// <summary>
		/// Get a configuration setting. <see cref="IRoleEnvironment.GetConfigurationSettingValue"/>
		/// </summary>
		/// <param name="roleEnvironment">
		/// The role Environment.
		/// </param>
		/// <param name="roleSettingName">
		/// The role Setting Name.
		/// </param>
		/// <returns>
		/// The get configuration setting.
		/// </returns>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking.")]
		public static string GetConfigurationSetting(this IRoleEnvironment roleEnvironment, string roleSettingName)
		{
			Assumes.NotNull(roleEnvironment, "roleEnvironment");

			string configurationSetting = roleEnvironment.GetConfigurationSettingValue(roleSettingName);

			if (configurationSetting == null)
			{
				throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Strings.CouldNotFindAppSetting, roleSettingName));
			}

			return configurationSetting;
		}

		/// <summary>
		/// Get a configuration setting. <see cref="IRoleEnvironment.GetConfigurationSettingValue"/>
		/// </summary>
		/// <param name="roleEnvironment">
		/// The role Environment.
		/// </param>
		/// <param name="roleSettingName">
		/// The role Setting Name.
		/// </param>
		/// <param name="trace">
		/// The trace.
		/// </param>
		/// <returns>
		/// The get bool configuration setting.
		/// </returns>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking."), 
		 SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bool", Justification = "Bool is the type of value we are getting so in this extension case it is OK.")]
		public static bool GetBoolConfigurationSetting(
			this IRoleEnvironment roleEnvironment, string roleSettingName, ITrace trace)
		{
			Assumes.NotNull(roleEnvironment, "roleEnvironment");
			Assumes.NotNull(trace, "trace");

			try
			{
				return bool.Parse(GetConfigurationSetting(roleEnvironment, roleSettingName));
			}
			catch (FormatException exception)
			{
				trace.Error(Strings.CouldNotParseKey, "bool", roleSettingName, exception.Message);
				throw;
			}
		}

		/// <summary>
		/// Try get a configuration setting. <see cref="IRoleEnvironment.GetConfigurationSettingValue"/>
		/// </summary>
		/// <param name="roleEnvironment">
		/// The role Environment.
		/// </param>
		/// <param name="roleSettingName">
		/// The role Setting Name.
		/// </param>
		/// <param name="trace">
		/// The trace.
		/// </param>
		/// <param name="value">
		/// The value.
		/// </param>
		/// <returns>
		/// True if the configuration setting was present.
		/// </returns>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking."), 
		 SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking."), 
		 SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "bool", Justification = "Bool is the type of value we are getting so in this extension case it is OK.")]
		public static bool TryGetBoolConfigurationSetting(
			this IRoleEnvironment roleEnvironment, string roleSettingName, ITrace trace, out bool value)
		{
			Assumes.NotNull(roleEnvironment, "roleEnvironment");
			Assumes.NotNull(trace, "trace");

			try
			{
				Assumes.NotNull(roleEnvironment, "roleEnvironment");
				string settingValue;
				if (roleEnvironment.TryGetConfigurationSettingValue(roleSettingName, out settingValue))
				{
					value = bool.Parse(settingValue);
					return true;
				}
			}
			catch (FormatException exception)
			{
				trace.Error(Strings.CouldNotParseKey, "bool", roleSettingName, exception.Message);
			}

			value = false;
			return false;
		}

		/// <summary>
		/// Get a configuration setting as an integer. <see cref="IRoleEnvironment.GetConfigurationSettingValue"/>
		/// </summary>
		/// <param name="roleEnvironment">
		/// The role Environment.
		/// </param>
		/// <param name="roleSettingName">
		/// The role Setting Name.
		/// </param>
		/// <param name="trace">
		/// The trace.
		/// </param>
		/// <returns>
		/// The get a configuration setting as an <see cref="int"/>.
		/// </returns>
		[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "AzureContrib.WindowsAzure.Core.Assumes.NotNull handles null checking."), 
		 SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "int", Justification = "Int is the type of value we are getting so in this extension case it is OK.")]
		public static int GetIntConfigurationSetting(
			this IRoleEnvironment roleEnvironment, string roleSettingName, ITrace trace)
		{
			Assumes.NotNull(roleEnvironment, "roleEnvironment");
			Assumes.NotNull(trace, "trace");
			try
			{
				return int.Parse(GetConfigurationSetting(roleEnvironment, roleSettingName), CultureInfo.CurrentCulture);
			}
			catch (FormatException exception)
			{
				trace.Error(Strings.CouldNotParseKey, "int", roleSettingName, exception.Message);
				throw;
			}
		}
	}
}